#include "scheduler.h"
#include "printf.h"
#include "pmm.h"
// 删除这一行: #include <string.h>  <-- 删除此行

// --------------------------
// 新增: 手动实现必需的字符串函数
// --------------------------

// 实现memset函数: 将内存块设置为指定值
static void* my_memset(void* s, int c, size_t n) {
    unsigned char* p = (unsigned char*)s;
    while (n--) {
        *p++ = (unsigned char)c;
    }
    return s;
}

// 实现strncpy函数: 复制字符串(最多n个字符)
static char* my_strncpy(char* dest, const char* src, size_t n) {
    size_t i;
    for (i = 0; i < n && src[i] != '\0'; i++) {
        dest[i] = src[i];
    }
    for (; i < n; i++) {
        dest[i] = '\0';
    }
    return dest;
}

// 将标准函数名映射到自定义实现
#define memset my_memset
#define strncpy my_strncpy

// --------------------------
// 以下是原scheduler.c的代码(保持不变)
// --------------------------

// 任务队列头指针和当前任务指针
static task_t* task_list = NULL;
static task_t* current_task = NULL;
static uint32_t next_pid = 1;

// 空闲任务(系统默认任务,PID=0)
static void idle_task(void* arg) {
    (void)arg;  // 参数未使用
    while (1) {
        __asm__ __volatile__("wfi");  // 等待中断
    }
}

// 初始化调度器
void scheduler_init(void) {
    printf("\n=== 调度器初始化 ===\n");
    
    // 创建空闲任务(当没有其他任务可运行时执行)
    int idle_pid = create_task("idle", idle_task, NULL, 100);
    if (idle_pid < 0) {
        printf("[错误] 创建空闲任务失败!\n");
        return;
    }
    
    // 设置空闲任务为当前任务
    current_task = task_list;
    current_task->state = TASK_RUNNING;
    
    printf("调度器初始化完成(空闲任务PID=%d)\n", idle_pid);
}

// 创建新任务
int create_task(const char* name, void (*entry)(void*), 
                void* arg, uint32_t time_slice) {
    // 分配任务控制块(使用一个物理页存储PCB)
    task_t* task = (task_t*)alloc_page();
    if (!task) {
        printf("[错误] 创建任务失败: 内存分配失败\n");
        return -1;
    }
    
    // 初始化任务控制块(清零所有字段)
    memset(task, 0, sizeof(task_t));  // 现在使用我们自己实现的memset
    task->pid = next_pid++;
    strncpy(task->name, name, 31);    // 现在使用我们自己实现的strncpy
    task->name[31] = '\0';
    task->state = TASK_READY;
    task->time_slice = time_slice;
    task->elapsed_time = 0;
    task->entry = entry;
    task->arg = arg;
    task->next = NULL;
    
    // 插入任务队列(尾插法)
    if (task_list == NULL) {
        task_list = task;
    } else {
        task_t* tail = task_list;
        while (tail->next != NULL) {
            tail = tail->next;
        }
        tail->next = task;
    }
    
    printf("[调度器] 创建任务成功: PID=%d, Name='%s', TimeSlice=%dms\n",
           task->pid, task->name, task->time_slice);
    
    return task->pid;
}

// 任务调度函数(Round-Robin轮转算法)
void schedule(void) {
    if (!current_task || !task_list) {
        return;
    }
    
    task_t* prev_task = current_task;
    
    // 将当前任务状态改为就绪(如果还在运行)
    if (current_task->state == TASK_RUNNING) {
        current_task->state = TASK_READY;
    }
    
    // 选择下一个就绪任务
    task_t* next = current_task->next;
    if (next == NULL) {
        next = task_list;  // 循环到队首
    }
    
    // 跳过非就绪任务(最多遍历一轮)
    int attempts = 0;
    int total_tasks = 0;
    task_t* tmp = task_list;
    while (tmp) {
        total_tasks++;
        tmp = tmp->next;
    }
    
    while (next->state != TASK_READY && attempts < total_tasks) {
        next = next->next ? next->next : task_list;
        attempts++;
    }
    
    // 如果没有就绪任务,继续运行当前任务
    if (next->state != TASK_READY) {
        current_task->state = TASK_RUNNING;
        return;
    }
    
    // 执行任务切换
    current_task = next;
    current_task->state = TASK_RUNNING;
    current_task->elapsed_time = 0;  // 重置时间片计数
    
    printf("[调度] 任务切换: %s(PID=%d) -> %s(PID=%d)\n",
           prev_task->name, prev_task->pid,
           current_task->name, current_task->pid);
}

// 获取当前任务
task_t* get_current_task(void) {
    return current_task;
}

// 打印所有任务信息
void print_tasks(void) {
    printf("\n=== 任务列表 ===\n");
    printf("%-5s %-15s %-12s %-10s %-10s\n",
           "PID", "Name", "State", "TimeSlice", "Elapsed");
    printf("-----------------------------------------------------\n");
    
    const char* state_str[] = {"READY", "RUNNING", "BLOCKED", "TERMINATED"};
    
    task_t* task = task_list;
    while (task != NULL) {
        printf("%-5d %-15s %-12s %-10dms %-10dms\n",
               task->pid, task->name, state_str[task->state],
               task->time_slice, task->elapsed_time);
        task = task->next;
    }
    printf("================\n\n");
}

